//
//  Level01Layer.cpp
//  Space shooting
//
//  Created by Raiden on 9/4/13.
//
//

#include "Level01Layer.h"
#include "Constants.h"
#include "StateManager.h"
#include "Player.h"
#include "Enemy01.h"
#include "SimpleAudioEngine.h"
#include "Game.h"
#include "Bullet01.h"
#include "CCProgressTimer.h"

using namespace std;

Level01Layer::Level01Layer() {
    
    size = CCDirector::sharedDirector()->getWinSize();
    
    homeBg = CCSprite::create("level01.png");
    homeBg->setPosition(ccp(size.width/2, 0 + homeBg->getContentSize().height/2) );
    addChild(homeBg);
    
    // Add player
    player = Player::create();
    player->setPosition(ccp(size.width/2, 50));
    
    addChild(player);
    
    // Call game loop method
    scheduleUpdate();
    
    // Add enemy to scene every 1 second
    schedule(schedule_selector(Level01Layer::addEnemy), 2);
    
    // Alway set touch after init method
    setTouchEnabled(true);
    
    displayMenu();
    
}

void Level01Layer::addWave01() {
    
    Game::getInstance()->waveType01();
}

void Level01Layer::addWave02() {
    
    Game::getInstance()->waveType02();
}

void Level01Layer::addWave03() {
    
    Game::getInstance()->waveType03();
}

void Level01Layer::addWave04() {
    
    Game::getInstance()->waveType04();
}
void Level01Layer::displayMenu() {
    
    CCSprite *hpBorder = CCSprite::create("hp_border.png");
    hpBorder->setPosition(ccp(hpBorder->getContentSize().width/2 + 5, size.height - hpBorder->getContentSize().height/2 - 5));
    
    CCSprite *hpBg = CCSprite::create("hp_background.png");    
    
    hpBar = CCProgressTimer::create(hpBg);
    hpBar->setType(kCCProgressTimerTypeBar);
    hpBar->setBarChangeRate(ccp(1, 0));
    hpBar->setMidpoint(ccp(0, 0));
    
    hpBar->setPercentage(0);
    hpBar->setPosition(hpBorder->getPosition());
    
    addChild(hpBar);
    addChild(hpBorder);
    
    // Add game score
    score = CCLabelBMFont::create("0", "font_num_green.fnt");
    score->setPosition(ccp(score->getContentSize().width/2 + 5, size.height - score->getContentSize().height/2 - hpBorder->getContentSize().height - 5));
    score->setAnchorPoint(ccp(0, 0.5));
    addChild(score);
    
    // Save score position
    Game::getInstance()->scorePoint = score->getPosition();
    
    // Add pause button
    CCMenu *menu= CCMenu::create();
    menu->setPosition(CCPointZero);
    
    CCMenuItemImage *pauseMenu = CCMenuItemImage::create("pause_icon.png", "pause_icon.png", this, menu_selector(Level01Layer::menuItemCallback));
    pauseMenu->setPosition(ccp(size.width - pauseMenu->getContentSize().width/2 - 5, size.height - pauseMenu->getContentSize().height/2 - 5));
    
    menu->addChild(pauseMenu);
    addChild(menu);
}
    
Level01Layer::~Level01Layer() {
    removeAllChildrenWithCleanup(true);
}

void Level01Layer::addEnemy() {
    
    Enemy01 *enemy = Enemy01::create("ship_04.png");
    
    float begin = enemy->getContentSize().width/2;
    int end = size.width - enemy->getContentSize().width;
    
    enemy->setPosition(ccp(rand() % end + begin, size.height + enemy->getContentSize().height));
    enemy->move();
    
    EnemyList->addObject(enemy);
    
    // Add to scene
    addChild(enemy);
}

void Level01Layer::update(float dt) {
    
    CCLOG("Time %d", timer);
    timer++;
        
    if(timer == 100) {
        schedule(schedule_selector(Level01Layer::addWave03), 0.3, 5, 0);
    }
    
    if(timer == 400) {
        schedule(schedule_selector(Level01Layer::addWave04), 0.3, 5, 0);
    }
    
    if(timer == 700) {
        schedule(schedule_selector(Level01Layer::addWave01), 0.3, 5, 0);
    }
    
    if(timer == 1000) {
        
        schedule(schedule_selector(Level01Layer::addWave02), 0.3, 5, 0);
    }
    
    // Scroll background down
    CCPoint pos = homeBg->getPosition();
    
    if(pos.y >= -(homeBg->getContentSize().height/2 - size.height))
        homeBg->setPosition(ccp(pos.x, pos.y - 0.3));
        
    // Set hp bar base on player hp
    float hpPercent = (player->hp * 100) / player->maxHp;
    hpBar->setPercentage(hpPercent);
    
    // Check collise
    
    CCObject *bullet;
    CCObject *enemy;
    CCObject *orb;
    
    if(GameStatus != GAME_STATUS_LOSE) {
     
        CCRect playerRect = CCRectMake(player->getPosition().x - (player->getContentSize().width/2),
                                       player->getPosition().y - (player->getContentSize().height/2),
                                       player->getContentSize().width,
                                       player->getContentSize().height);
        
        // Check collise between enemy and player
        CCARRAY_FOREACH(EnemyList, enemy) {
            
            Enemy01 *enemySprite = dynamic_cast<Enemy01*>(enemy);
            
            CCRect enemyRect = CCRectMake(enemySprite->getPosition().x - (enemySprite->getContentSize().width/2),
                                          enemySprite->getPosition().y - (enemySprite->getContentSize().height/2),
                                          enemySprite->getContentSize().width,
                                          enemySprite->getContentSize().height);
            
            if(enemyRect.intersectsRect(playerRect)) {
                player->hp -= 1;
                enemySprite->hp = 0;
            }
        }
        
        // Check collise between player and orb
        CCARRAY_FOREACH(OrbList, orb) {
            
            CCMWSprite *orbSprite = dynamic_cast<CCMWSprite*>(orb);
            CCRect orbRect = CCRectMake(orbSprite->getPosition().x - (orbSprite->getContentSize().width/2),
                                         orbSprite->getPosition().y - (orbSprite->getContentSize().height/2),
                                         orbSprite->getContentSize().width,
                                         orbSprite->getContentSize().height);
            
            if(orbRect.intersectsRect(playerRect)) {
                player->orbNumber += 1;
                OrbList->removeObject(orbSprite);
                removeChild(orbSprite, true);
            }
        }
    }
    
    // Loop througth bullet list
    CCARRAY_FOREACH(BulletList, bullet) {
        
        Bullet01 *bulletSprite = dynamic_cast<Bullet01*>(bullet);
        CCRect bulletRect = CCRectMake(bulletSprite->getPosition().x - (bulletSprite->getContentSize().width/2),
                                           bulletSprite->getPosition().y - (bulletSprite->getContentSize().height/2),
                                           bulletSprite->getContentSize().width,
                                           bulletSprite->getContentSize().height);
        
        // Loop througth enemy list
        CCARRAY_FOREACH(EnemyList, enemy) {
            
            Enemy01 *enemySprite = dynamic_cast<Enemy01*>(enemy);
            
            CCRect enemyRect = CCRectMake(enemySprite->getPosition().x - (enemySprite->getContentSize().width/2),
                                               enemySprite->getPosition().y - (enemySprite->getContentSize().height/2),
                                               enemySprite->getContentSize().width,
                                               enemySprite->getContentSize().height);
            
            // Check collise between to object
            if(bulletRect.intersectsRect(enemyRect)) {
                
                // Update enemy hp base on bullet damage
                enemySprite->hp -= bulletSprite->damage;
               
                this->removeChild(bulletSprite);
                BulletList->removeObject(bulletSprite);
                
                // Set game score
                Game::getInstance()->gameScore += enemySprite->score;
            }
        }
    }
    
    // Parse game score to string
    char txt[16];
    sprintf(txt, "%d", Game::getInstance()->gameScore);
    
    // Set new score
    score->setString(txt);
}

void Level01Layer::ccTouchesMoved(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent) {
    
    if(!player->isDead) {
        
        CCTouch *touch = (CCTouch* ) pTouches->anyObject();
        
        // Get previos touch point
        CCPoint previousPoint = touch->getPreviousLocation();
        
        // Get current touch point
        CCPoint presentPoint = touch->getLocation();
        
        CCLOG("X %f %f", presentPoint.x, presentPoint.x);
        CCLOG("Y %f %f", previousPoint.y, presentPoint.y);
        
        // Calculate distance between two point
        float moveX = presentPoint.x - previousPoint.x;
        float moveY = presentPoint.y - previousPoint.y;
        
        if(checkInbound(moveX, moveY)) {
            
            CCPoint position = player->getPosition();
        
            // Move player
            player->setPosition(ccp(position.x + moveX, position.y + moveY));
        }
    }
}

bool Level01Layer::checkInbound(int x, int y) {
    
    CCPoint position = player->getPosition();
    
    // Left edge
    if(position.x + x < player->getContentSize().width/2) {
        return false;
    }
    
    // Righr edge
    if(position.x + x > size.width - player->getContentSize().width/2) {
        return false;
    }
    
    // Top
    if(position.y + y > size.height - player->getContentSize().height/2) {
        return false;
    }
    
    // Bottom
    if(position.y + y < 0 + player->getContentSize().height/2) {
        return false;
    }
    
    return true;
}

void Level01Layer::menuItemCallback(CCObject *object)  {
    
    StateManager::getInstance()->switchScene(GAME_STATE_HOME);
    
}